<template>
    <div>
        <!-- 面包屑导航区域 -->
        <el-breadcrumb separator-class="el-icon-arrow-right">
            <el-breadcrumb-item>集群管理</el-breadcrumb-item>
            <el-breadcrumb-item :to="{ path: '/cluster' }">集群信息列表</el-breadcrumb-item>
            <el-breadcrumb-item>添加集群</el-breadcrumb-item>
        </el-breadcrumb>

        <!-- 步骤条 -->
        <div class="step-panel">
            <el-steps :active="pageStepNo" align-center>
                <el-step title="① 常规配置" icon="el-icon-user-solid" description="集群命名及配置操作系统用户"></el-step>
                <el-step title="② 基本配置" icon="el-icon-info" description="配置数据库较为常用的参数"></el-step>
                <el-step title="③ 高级配置" icon="el-icon-warning" description="配置数据库较为高级的参数"></el-step>
            </el-steps>
        </div>

        <!-- 表单输入区 -->
        <el-form ref="addFormRef" :model="addForm" :rules="addFormRules" label-width="180px">

            <el-carousel height="580px" :autoplay="false" arrow="never" indicator-position="none" :loop="false" ref="carouselRef" @change="carouselChange">

                <el-carousel-item key="normal">
                    <div class="form-div">
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="集群名称" prop="name">
                                    <el-input v-model="addForm.name" maxlength="30" show-word-limit></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="SSH监听端口" prop="ssh_port">
                                    <el-input-number v-model="addForm.ssh_port" controls-position="right" :min="1" :max="65536"></el-input-number>
                                </el-form-item>
                            </el-col>
                        </el-row>

                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="系统普通用户名" prop="user_normal">
                                    <el-input v-model="addForm.user_normal"></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="系统管理员密码" prop="root_password">
                                    <el-input v-model="addForm.root_password" show-password></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>

                        <el-form-item label="数据库安装路径" prop="installation_path">
                            <el-input :value="addForm.installation_path | replacePath(addForm.name, addForm.user_normal)" readonly></el-input>
                        </el-form-item>

                        <el-form-item label="归档文件目录" prop="archive_path">
                            <el-input :value="addForm.archive_path | replacePath(addForm.name, addForm.user_normal)" readonly></el-input>
                        </el-form-item>

                        <el-form-item label="信任网关" prop="trust_servers">
                            <el-tag 
                                :key="tag" 
                                v-for="tag in addForm.trust_servers" 
                                closable :disable-transitions="false" 
                                @close="handleClose(tag)">
                                {{tag}}
                            </el-tag>
                            <el-input 
                                class="input-new-tag" 
                                v-if="inputVisible" 
                                v-model="inputValue" 
                                ref="saveTagInput" 
                                size="small" 
                                @keyup.enter.native="handleInputConfirm" 
                                @blur="handleInputConfirm">
                            </el-input>
                            <el-button v-else class="button-new-tag" size="small" @click="showInput">+ 新 增</el-button>
                        </el-form-item>

                        <el-form-item label="HA日志文件" prop="log_file">
                            <el-input :value="addForm.log_file | replacePath(addForm.name, addForm.user_normal)" readonly></el-input>
                        </el-form-item>

                        <el-form-item label="数据库data目录" prop="data_directory">
                            <el-input :value="addForm.data_directory | replacePath(addForm.name, addForm.user_normal)" readonly></el-input>
                        </el-form-item>

                        <el-form-item label="数据库bin目录" prop="pg_bin_dir">
                            <el-input :value="addForm.pg_bin_dir | replacePath(addForm.name, addForm.user_normal)" readonly></el-input>
                        </el-form-item>

                        <el-form-item label="HA PID文件" prop="hamgr_pid_file">
                            <el-input :value="addForm.hamgr_pid_file | replacePath(addForm.name, addForm.user_normal)" readonly></el-input>
                        </el-form-item>
                    </div>
                </el-carousel-item>

                <el-carousel-item key="basic">
                    <div class="form-div">
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="最大连接数" prop="max_connections">
                                    <el-input-number v-model="addForm.max_connections" controls-position="right" :min="10" :max="500"></el-input-number>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="数据库监听端口" prop="db_port">
                                    <el-input-number v-model="addForm.db_port" controls-position="right" :min="1" :max="65536"></el-input-number>
                                </el-form-item>
                            </el-col>
                        </el-row>

                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="数据库管理员用户" prop="db_user">
                                    <el-input v-model="addForm.db_user"></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="数据库用户密码" prop="db_password">
                                    <el-input v-model="addForm.db_password" show-password></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>

                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="复制模式" prop="replication_mode">
                                    <el-select v-model="addForm.replication_mode" placeholder="请选择复制模式">
                                        <el-option label="sync" value="sync"></el-option>
                                        <el-option label="async" value="async"></el-option>
                                        <el-option label="quorum" value="quorum"></el-option>
                                    </el-select>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="兼容模式" prop="db_mode">
                                    <el-select v-model="addForm.db_mode" placeholder="请选择数据库兼容模式">
                                        <el-option label="oracle" value="oracle"></el-option>
                                        <el-option label="pg" value="pg"></el-option>
                                    </el-select>
                                </el-form-item>
                            </el-col>
                        </el-row>

                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="加密方式" prop="encryption">
                                    <el-select v-model="addForm.encryption" placeholder="请选择加密方式">
                                        <el-option label="md5" value="md5"></el-option>
                                        <el-option label="trust" value="trust"></el-option>
                                    </el-select>
                                </el-form-item>
                            </el-col>
                        </el-row>

                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="HA库名" prop="hamgr_dbname">
                                    <el-input v-model="addForm.hamgr_dbname" disabled></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="HA库用户" prop="hamgr_dbuser">
                                    <el-input v-model="addForm.hamgr_dbuser" disabled></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>

                        <el-form-item label="ping命令路径" prop="ping_path">
                            <el-input v-model="addForm.ping_path"></el-input>
                        </el-form-item>
                    </div>
                </el-carousel-item>

                <el-carousel-item key="advance">
                    <div class="form-div">
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="备服务器WAL文件数" prop="wal_keep_segments">
                                    <el-input-number v-model="addForm.wal_keep_segments" controls-position="right" :min="8" :max="1024"></el-input-number>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="进程最大数" prop="max_wal_senders">
                                    <el-input-number v-model="addForm.max_wal_senders" controls-position="right" :min="16" :max="256"></el-input-number>
                                </el-form-item>
                            </el-col>
                        </el-row>

                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="热备反馈" prop="hot_standby_feedback">
                                    <el-select v-model="addForm.hot_standby_feedback" placeholder="请选择是否启用热备反馈">
                                        <el-option label="on" value="on"></el-option>
                                        <el-option label="off" value="off"></el-option>
                                    </el-select>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="编码格式" prop="server_encoding">
                                    <el-select v-model="addForm.server_encoding" placeholder="请选择数据库编码格式">
                                        <el-option label="default" value="default"></el-option>
                                        <el-option label="utf8" value="utf8"></el-option>
                                        <el-option label="gbk" value="gbk"></el-option>
                                    </el-select>
                                </el-form-item>
                            </el-col>
                        </el-row>

                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="虚拟IP地址" prop="virtual_ip">
                                    <el-input v-model="addForm.virtual_ip"></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="虚拟子网掩码" prop="virtual_ip_mask">
                                    <el-input v-model="addForm.virtual_ip_mask"></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>

                        <el-form-item label="arping命令路径" prop="arping_path">
                            <el-input v-model="addForm.arping_path"></el-input>
                        </el-form-item>
                        <el-form-item label="ip命令路径" prop="ip_path">
                            <el-input v-model="addForm.ip_path"></el-input>
                        </el-form-item>
                        <el-form-item label="SSH 参数" prop="ssh_options">
                            <el-input v-model="addForm.ssh_options"></el-input>
                        </el-form-item>

                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="重连尝试次数" prop="reconnect_attempts">
                                    <el-input-number v-model="addForm.reconnect_attempts" controls-position="right" :min="2" :max="20"></el-input-number>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="重连次数间隔" prop="reconnect_interval">
                                    <el-input-number v-model="addForm.reconnect_interval" controls-position="right" :min="1" :max="10"></el-input-number>
                                </el-form-item>
                            </el-col>
                        </el-row>

                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="故障转移方式" prop="failover">
                                    <el-select v-model="addForm.failover" placeholder="请选择故障转移方式">
                                        <el-option label="manual" value="manual"></el-option>
                                        <el-option label="automatic" value="automatic"></el-option>
                                    </el-select>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="恢复方式" prop="recovery">
                                    <el-select v-model="addForm.recovery" placeholder="请选择恢复方式">
                                        <el-option label="manual" value="manual"></el-option>
                                        <el-option label="automatic" value="automatic"></el-option>
                                    </el-select>
                                </el-form-item>
                            </el-col>
                        </el-row>
                    </div>
                </el-carousel-item>

            </el-carousel>
        </el-form>

        <div class="div-submit">
            <el-button type="danger" icon="el-icon-caret-left" @click="cancel">取 消</el-button>
            <el-button type="primary" icon="el-icon-back" @click="previousStep" :disabled="pageStepNo <= 0">上一步</el-button>
            <el-button type="primary" @click="nextStep" :disabled="pageStepNo >= 2">下一步<i class="el-icon-right el-icon--right"></i></el-button>
            <el-button type="success" icon="el-icon-finished" @click="finish">完 成</el-button>
        </div>
        
    </div>
</template>

<script>
export default {
    data: function () {
        var checkClusterName = async (rule, value, callback) => {
            const result = await this.$http.get('clusters', {
                params: {
                    query: value,
                    pagenum: 1,
                    pagesize: 9999
                }
            });
            const res = result.data;
            if (res.meta.status !== 200) {
                callback(new Error(`查询集群信息失败：${res.meta.msg}`));
            } else if (res.data.clusters.some(item => item.name === value)) {
                callback(new Error(`集群名称 ${value} 已存在！`));
            } else {
                callback();
            }
        }
        return {
            templateExample: {},
            pageStepNo: 0,
            inputVisible: false,
            inputValue: '',
            addForm: {
                // 常规配置
                name: "",
                ssh_port: 22,
                user_normal: "",
                root_password: "",
                installation_path: "/home/<user>/DBClusters/<name>",
                archive_path: "/home/<user>/DBClusters/<name>/postgres/archive",
                trust_servers: [],
                log_file: "/home/<user>/DBClusters/<name>/postgres/hamgr.log",
                data_directory: "/home/<user>/DBClusters/<name>/postgres/data",
                pg_bin_dir: "/home/<user>/DBClusters/<name>/postgres/bin",
                hamgr_pid_file: "/home/<user>/DBClusters/<name>/postgres/hamgrd.pid",

                // 基本配置
                max_connections: 100,
                db_port: 5432,
                db_user: "dbadmin",
                db_password: "123456",
                replication_mode: "quorum",
                db_mode: "oracle",
                encryption: "md5",
                wal_keep_segments: 512,
                max_wal_senders: 32,
                hot_standby_feedback: "on",
                server_encoding: "default",

                // 高级配置
                hamgr_dbname: "repmgr",
                hamgr_dbuser: "repmgr",
                ping_path: "/usr/bin",
                virtual_ip: "",
                virtual_ip_mask: "",
                arping_path: "/sbin",
                ip_path: "/sbin",
                ssh_options: "-q -o ConnectTimeout=10 -o StrictHostKeyChecking=no",
                reconnect_attempts: 3,
                reconnect_interval: 5,
                failover: "automatic",
                recovery: "manual"
            },
            addFormRules: {
                // 常规配置
                name: [
                    { required: true, message: '请输入集群名称', trigger: 'blur' },
                    { min: 3, max: 30, message: '集群名称的长度在 3 ~ 30 个字符之间', trigger: 'blur' },
                    { validator: checkClusterName, trigger: 'blur' }
                ],
                ssh_port: [
                    { required: true, message: '请输入SSH监听端口号', trigger: 'blur' },
                    { type: 'number', message: '请输入正确的SSH监听端口号', trigger: ['blur', 'change'] }
                ],
                user_normal: [
                    { required: true, message: '请输入系统普通用户名', trigger: 'blur' },
                    { min: 3, max: 30, message: '用户登录名的长度在 3 ~ 30 个字符之间', trigger: 'blur' }
                ],
                root_password: [
                    { required: true, message: '请输入系统管理员密码', trigger: 'blur' },
                    { min: 3, max: 15, message: '系统管理员密码的长度在 3 ~ 15 个字符之间', trigger: 'blur' }
                ],
                trust_servers: [
                    { required: true, message: '请至少输入一个信任网关', trigger: 'blur' },
                ],
                // 基本配置
                max_connections: [
                    { required: true, message: '请输入最大连接数', trigger: 'blur' },
                    { type: 'number', message: '请输入正确的最大连接数', trigger: ['blur', 'change'] }
                ],
                db_port: [
                    { required: true, message: '请输入数据库监听端口号', trigger: 'blur' },
                    { type: 'number', message: '请输入正确的数据库监听端口号', trigger: ['blur', 'change'] }
                ],
                db_password: [
                    { required: true, message: '请输入数据库管理员密码', trigger: 'blur' },
                    { min: 3, max: 15, message: '数据库管理员密码的长度在 3 ~ 15 个字符之间', trigger: 'blur' }
                ],
                wal_keep_segments: [
                    { required: true, message: '请输入备用服务器保留的WAL文件数', trigger: 'blur' },
                    { type: 'number', message: '请输入正确的备用服务器保留的WAL文件数', trigger: ['blur', 'change'] }
                ],
                max_wal_senders: [
                    { required: true, message: '请输入WAL Sender进程最大数', trigger: 'blur' },
                    { type: 'number', message: '请输入正确WAL Sender进程最大数', trigger: ['blur', 'change'] }
                ]
            }
        }
    },
    filters: {
        replacePath: function (val, name, user) {
            const keyWordName = '<name>';
            const keyWordUser = '<user>'
            const valueName = name.length > 0 ? name : keyWordName;
            const valueUser = user.length > 0 ? user : keyWordUser;
            
            return val
                .replace(keyWordName, valueName)
                .replace(keyWordUser, valueUser);
        }
    },
    mounted: async function () {
        await this.getTemplateById(this.$route.query.tid);
        for (var attr in this.templateExample) {
            if (attr === 'name') {
                continue;
            }
            this.addForm[attr] = this.templateExample[attr];
        }
    },
    methods: {
        getTemplateById: async function (id) {
            if (id <= 0) return;

            const result = await this.$http.get(`templates/${id}`);
            const res = result.data;
            if (res.meta.status !== 201) return this.$message.error(`根据ID获取模板失败：${res.meta.msg}`);
            this.templateExample = res.data;
        },
        cancel: function () {
            this.$router.push('/cluster');
        },
        previousStep: function () {
            if (this.pageStepNo <= 0) return;
            this.pageStepNo -= 1;
            this.$refs.carouselRef.setActiveItem(this.pageStepNo)
            // this.$refs.carouselRef.prev();
        },
        nextStep: function () {
            if (this.pageStepNo >= 2) return;
            this.pageStepNo += 1;
            this.$refs.carouselRef.setActiveItem(this.pageStepNo)
            // this.$refs.carouselRef.next();
        },
        finish: function () {
            this.$refs.addFormRef.validate(async valid => {
                if (!valid) return this.$message.error(`集群配置信息填写不完整，请将校验失败的信息修改正确后再次尝试...`);

                const rm = await this.$confirm('基本信息校验完毕，点击 "确定" 按钮立即创建...', '确认', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).catch(err => err);
                if (rm !== 'confirm') return this.$message.info('已取消集群创建。');

                // 替换路径中的占位符关键字
                const formObj = JSON.parse(JSON.stringify(this.addForm));
                const replacePathFilter = this.$options.filters.replacePath;
                formObj.installation_path = replacePathFilter(formObj.installation_path, formObj.name, formObj.user_normal);
                formObj.archive_path = replacePathFilter(formObj.archive_path, formObj.name, formObj.user_normal);
                formObj.log_file = replacePathFilter(formObj.log_file, formObj.name, formObj.user_normal);
                formObj.data_directory = replacePathFilter(formObj.data_directory, formObj.name, formObj.user_normal);
                formObj.pg_bin_dir = replacePathFilter(formObj.pg_bin_dir, formObj.name, formObj.user_normal);
                formObj.hamgr_pid_file = replacePathFilter(formObj.hamgr_pid_file, formObj.name, formObj.user_normal);

                const result = await this.$http.post('clusters', formObj);
                const res = result.data;
                if (res.meta.status !== 201) return this.$message.error(`添加集群失败：${res.meta.msg}`);

                this.$router.push('/cluster');
                this.$message.success(`添加集群成功！`);
            });
        },
        carouselChange: function (currIdx, prevIdx) {
            console.log(`Current Index: ${currIdx}，previous index: ${prevIdx}`);
        },
        handleClose: function (tag) {
            this.addForm.trust_servers.splice(this.addForm.trust_servers.indexOf(tag), 1);
        },
        showInput: function () {
            this.inputVisible = true;
            this.$nextTick(_ => {
                this.$refs.saveTagInput.$refs.input.focus();
            });
        },
        handleInputConfirm: function () {
            const inputValue = this.inputValue;
            if (inputValue) {
                if (this.$check_IpAddr(inputValue)) {
                    this.$message.error(`信任网关地址 ${inputValue} 校验失败，请确认后重新输入正确的IP地址！`);
                } else if (this.addForm.trust_servers.some(value => value === inputValue)) {
                    this.$message.warning(`IP地址 ${inputValue} 已存在于信任网关列表中，无需重复输入。`);
                } else {
                    this.addForm.trust_servers.push(inputValue);
                }
            }
            this.inputVisible = false;
            this.inputValue = '';
        }
    }
}
</script>

<style lang="less" scoped>

    .step-panel {
        width: 90%;
        margin: 0 auto 25px;
    }

    .form-div {
        width: calc(80% - 200px);
        margin: 10px auto;
        // border: 1px solid black;
        padding-right: 50px;
    }

    .el-select,
    .el-input-number {
        width: 100%;
    }

    .div-submit {
        display: flex;
        width: 100%;
        margin: 20px 0;
        justify-content: center;
    }

    .el-tag {
        margin-right: 10px;
    }

    .button-new-tag {
        margin-right: 10px;
        height: 32px;
        line-height: 30px;
        padding-top: 0;
        padding-bottom: 0;
    }

    .input-new-tag {
        width: 135px;
        margin-right: 10px;
        vertical-align: bottom;
    }
</style>
